/*
 *  Note.h
 *  SoundController0002
 *
 *  Created by jiro on 10/10/02.
 *  Copyright 2010 jiro music. All rights reserved.
 *
 */

#pragma once

#include <string>
#include <cmath>
#include <iostream>
#include <string>
#include <iterator>

namespace sc
{

class Note { 
public:

	enum Id
	{
		Mute = -1,

		A = 0,

		ASharp = 1,
		BFlat = ASharp,

		B = 2,
		CFlat = B,

		C = 3,
		BSharp = C,

		CSharp = 4,
		DFlat = CSharp,
		
		D = 5,

		DSharp = 6,
		EFlat = DSharp,		
		
		E = 7,
		FFlat = E,

		F = 8,
		ESharp = F,

		FSharp = 9,
		GFlat = FSharp,

		G = 10,

		GSharp = 11,
		AFlat = GSharp,

		NoteIdCount = 12
	};

	enum MidiNumber
	{
		MidiNumberMute = -1,		//	this is not midi note, add this to availability
		CMinus1 = 0,
		BSharpMinus2 = 0,
		CSharpMinus1 = 1,
		DFlatMinus1 = 1,
		DMinus1 = 2,
		DSharpMinus1 = 3,
		EFlatMinus1 = 3,
		EMinus1 = 4,
		FFlatMinus1 = 4,
		FMinus1 = 5,
		ESharpMinus1 = 5,
		FSharpMinus1 = 6,
		GFlatMinus1 = 6,
		GMinus1 = 7,
		GSharpMinus1 = 8,
		AFlatMinus1 = 8,
		AMinus1 = 9,
		ASharpMinus1 = 10,
		BFlatMinus1 = 10,
		BMinus1 = 11,
		CFlatMinus1 = 11,
		C0 = 12,
		BSharpminus1 = 12,
		CSharp0 = 13,
		DFlat0 = 13,
		D0 = 14,
		DSharp0 = 15,
		EFlat0 = 15,
		E0 = 16,
		FFlat0 = 16,
		F0 = 17,
		ESharp0 = 17,
		FSharp0 = 18,
		GFlat0 = 18,
		G0 = 19,
		GSharp0 = 20,
		AFlat0 = 20,
		A0 = 21,
		ASharp0 = 22,
		BFlat0 = 22,
		B0 = 23,
		CFlat0 = 23,
		C1 = 24,
		BSharp0 = 24,
		CSharp1 = 25,
		DFlat1 = 25,
		D1 = 26,
		DSharp1 = 27,
		EFlat1 = 27,
		E1 = 28,
		FFlat1 = 28,
		F1 = 29,
		ESharp1 = 29,
		FSharp1 = 30,
		GFlat1 = 30,
		G1 = 31,
		GSharp1 = 32,
		AFlat1 = 32,
		A1 = 33,
		ASharp1 = 34,
		BFlat1 = 34,
		B1 = 35,
		CFlat1 = 35,
		C2 = 36,
		BSharp1 = 36,
		CSharp2 = 37,
		DFlat2 = 37,
		D2 = 38,
		DSharp2 = 39,
		EFlat2 = 39,
		E2 = 40,
		FFlat2 = 40,
		F2 = 41,
		ESharp2 = 41,
		FSharp2 = 42,
		GFlat2 = 42,
		G2 = 43,
		GSharp2 = 44,
		AFlat2 = 44,
		A2 = 45,
		ASharp2 = 46,
		BFlat2 = 46,
		B2 = 47,
		CFlat2 = 47,
		C3 = 48,
		BSharp2 = 48,
		CSharp3 = 49,
		DFlat3 = 49,
		D3 = 50,
		DSharp3 = 51,
		EFlat3 = 51,
		E3 = 52,
		FFlat3 = 52,
		F3 = 53,
		ESharp3 = 53,
		FSharp3 = 54,
		GFlat3 = 54,
		G3 = 55,
		GSharp3 = 56,
		AFlat3 = 56,
		A3 = 57,
		ASharp3 = 58,
		BFlat3 = 58,
		B3 = 59,
		CFlat3 = 59,
		C4 = 60,
		BSharp3 = 60,
		CSharp4 = 61,
		DFlat4 = 61,
		D4 = 62,
		DSharp4 = 63,
		EFlat4 = 63,
		E4 = 64,
		FFlat4 = 64,
		F4 = 65,
		ESharp4 = 65,
		FSharp4 = 66,
		GFlat4 = 66,
		G4 = 67,
		GSharp4 = 68,
		AFlat4 = 68,
		A4 = 69,
		ASharp4 = 70,
		BFlat4 = 70,
		B4 = 71,
		CFlat4 = 71,
		C5 = 72,
		BSharp4 = 72,
		CSharp5 = 73,
		DFlat5 = 73,
		D5 = 74,
		DSharp5 = 75,
		EFlat5 = 75,
		E5 = 76,
		FFlat5 = 76,
		F5 = 77,
		ESharp5 = 77,
		FSharp5 = 78,
		GFlat5 = 78,
		G5 = 79,
		GSharp5 = 80,
		AFlat5 = 80,
		A5 = 81,
		ASharp5 = 82,
		BFlat5 = 82,
		B5 = 83,
		CFlat5 = 83,
		C6 = 84,
		BSharp5 = 84,
		CSharp6 = 85,
		DFlat6 = 85,
		D6 = 86,
		DSharp6 = 87,
		EFlat6 = 87,
		E6 = 88,
		FFlat6 = 88,
		F6 = 89,
		ESharp6 = 89,
		FSharp6 = 90,
		GFlat6 = 90,
		G6 = 91,
		GSharp6 = 92,
		AFlat6 = 92,
		A6 = 93,
		ASharp6 = 94,
		BFlat6 = 94,
		B6 = 95,
		CFlat6 = 95,
		C7 = 96,
		BSharp6 = 96,
		CSharp7 = 97,
		DFlat7 = 97,
		D7 = 98,
		DSharp7 = 99,
		EFlat7 = 99,
		E7 = 100,
		FFlat7 = 100,
		F7 = 101,
		ESharp7 = 101,
		FSharp7 = 102,
		GFlat7 = 102,
		G7 = 103,
		GSharp7 = 104,
		AFlat7 = 104,
		A7 = 105,
		ASharp7 = 106,
		BFlat7 = 106,
		B7 = 107,
		CFlat7 = 107,
		C8 = 108,
		BSharp7 = 108,
		CSharp8 = 109,
		DFlat8 = 109,
		D8 = 110,
		DSharp8 = 111,
		EFlat8 = 111,
		E8 = 112,
		FFlat8 = 112,
		F8 = 113,
		ESharp8 = 113,
		FSharp8 = 114,
		GFlat8 = 114,
		G8 = 115,
		GSharp8 = 116,
		AFlat8 = 116,
		A8 = 117,
		ASharp8 = 118,
		BFlat8 = 118,
		B8 = 119,
		CFlat8 = 119,
		C9 = 120,
		BSharp8 = 120,
		CSharp9 = 121,
		DFlat9 = 121,
		D9 = 122,
		DSharp9 = 123,
		EFlat9 = 123,
		E9 = 124,
		FFlat9 = 124,
		F9 = 125,
		ESharp9 = 125,
		FSharp9 = 126,
		GFlat9 = 126,
		G9 = 127,

		//	these notes are added to make programming easily
		GSharp9 = 128,
		AFlat9 = 128,
		A9 = 129,
		ASharp9 = 130,
		BFlat9 = 130,
		B9 = 131,
		CFlat10 = 131,
		C10 = 132,
		BSharp9 = 132,
		CSharp10 = 133,
		DFlat10 = 133,
		D10 = 134,
		DSharp10 = 135,
		EFlat10 = 135,
		E10 = 136,
		FFlat10 = 136,
		F10 = 137,
		ESharp10 = 137,
		FSharp10 = 138,
		GFlat10 = 138,
		G10 = 139,
		GSharp10 = 140,
		AFlat10 = 140,
		A10 = 141,
		ASharp10 = 142,
		BFlat10 = 142,
		B10 = 143,
		CFlat11 = 143,

		MidiNumberCount = CFlat11 + 1,

	};
	
	enum Interval
	{
		Perfect1st = 0,

		Minor2nd = 1,

		Major2nd = 2,
		
		Minor3rd = 3,
		
		Major3rd = 4,
		
		Perfect4th = 5,
		
		Augment4th = 6,
		
		Perfect5th = 7,
		
		Minor6th = 8,
		
		Major6th = 9,
		
		Minor7th = 10,
		
		Major7th = 11,

	};

	static const double pianississimo = 0.2;

	static const double pianissimo = 0.25;

	static const double piano = 0.5;

	static const double mezzoPiano = 0.75;

	static const double mezzoForte = 1.0;
	
	static const double forte = 1.125;

	static const double fortissimo = 1.25;

	static const double fortississimo = 1.50;

public:

	static Interval GetInterval( Note::Id note0, Note::Id note1 );

	static Id GetNoteIdFrom( MidiNumber number );
	
	static int GetOctaveFrom( MidiNumber number );	

	static std::string ToString( Id noteId ) ;
	
	static std::string ToString( MidiNumber midiNumber );

	static std::string ToString( Interval pitch );
	
	static std::string IntervalToString( int pitchByChromaticCount, bool omissionExpression );

	template< class Container >
	static std::string ToString( const Container& chord );

};

}